package org.jfk.core.utils;


public class ByteUtils {
	
	/**
	 * 字节数组高地位反转
	 * @param a
	 * @return
	 */
	public static byte[] bytesInverse(byte[] a){
		if (a == null){
			return null;
		}
		byte[] b = new byte[a.length];
		for (int i = 0 ,j = b.length - 1 ; i < a.length ; i++,j--){
			b[j] = a[i];
		}
		return b;
	}
	/**
	 * 将2个字节转为整数 bytes[0]=0x01; bytes[1] = 0x00;
	 * 
	 * @param bytes
	 * @return
	 */
	public static int byte2ToInt(byte[] bytes) {
		int value = 0;
		// 由高位到低位
		for (int i = 0; i < 2; i++) {
			int shift = (2 - 1 - i) * 8;
			value += (bytes[i] & 0x00FF) << shift;// 往高位游
		}
		return value;
	}

	/**
	 * 将4个字节转为整数 bytes[0]=0x00; bytes[1]=0x00; bytes[2]=0x01; bytes[3] = 0x00;
	 * 
	 * @param bytes
	 * @return
	 */
	public static int byte4ToInt(byte[] b) {
		int mask = 0xff;
		int temp = 0;
		int n = 0;
		for (int i = 0; i < 4; i++) {
			n <<= 8;
			temp = b[i] & mask;
			n |= temp;
		}
		return n;
	}  
	
	public static String bytesToASCII(byte[] b){
		StringBuffer s = new StringBuffer("");
		for (int i = 0 ; i < b.length ; i++){
			char c = (char) b[i];
			s.append(c);
		}
		return s.toString();
	}
	
	public static byte ASCIITobyte(char c){
		byte b = (byte) c;
		return b;
	}
	
	/**
	 * 将被编成ASCII的数据转为原始数据
	 * （注：tbox项目中用到）
	 * @param b
	 * @return
	 */
	public static byte[] ASCIIBufferToHexBuffer(byte[] b){
		byte[] bb = new byte[b.length/2];
		int j = 0;
		for (int i = 0 ; i < b.length-1 ; i=i+2){
			byte b1 = (byte)Character.digit(b[i], 32);
			byte b2 = (byte)Character.digit(b[i+1], 32);
			bb[j++] = (byte) (b1<<4 | b2);	
		}
		return bb;
	}
	
	public static byte[] strToASCII(String s){
		char[] c = s.toCharArray();
		byte[] b = new byte[c.length];
		for (int i = 0 ; i < c.length ; i++){
			b[i] = (byte) c[i];
		}
		return b;
	}
	
	
	public static long byte8Tolong(byte[] bb) {
	       return ((((long) bb[ 0] & 0xff) << 56) 
	               | (((long) bb[ 1] & 0xff) << 48) 
	               | (((long) bb[ 2] & 0xff) << 40) 
	               | (((long) bb[ 3] & 0xff) << 32) 
	               | (((long) bb[ 4] & 0xff) << 24) 
	               | (((long) bb[ 5] & 0xff) << 16) 
	               | (((long) bb[ 6] & 0xff) << 8) 
	               | (((long) bb[ 7] & 0xff) << 0)); 
	} 
	
	public static long byte4Tolong(byte[] bb) {
	       return ((((long) 0 & 0xff) << 56) 
	               | (((long) 0 & 0xff) << 48) 
	               | (((long) 0 & 0xff) << 40) 
	               | (((long) 0 & 0xff) << 32) 
	               | (((long) bb[ 0] & 0xff) << 24) 
	               | (((long) bb[ 1] & 0xff) << 16) 
	               | (((long) bb[ 2] & 0xff) << 8) 
	               | (((long) bb[ 3] & 0xff) << 0)); 
	}	

	public static byte[] intToWord(int i) {
		byte[] result = new byte[2];
		result[0] = (byte) ((i >> 8) & 0xFF);
		result[1] = (byte) (i & 0xFF);
		return result;
	}
	
	public static String intToWordString(int i) {
		return byteToHexString(intToWord(i));
	}	

	public static byte[] intToDWord(int i) {
		byte[] result = new byte[4];
		result[0] = (byte) ((i >> 24) & 0xFF);
		result[1] = (byte) ((i >> 16) & 0xFF);
		result[2] = (byte) ((i >> 8) & 0xFF);
		result[3] = (byte) (i & 0xFF);
		return result;
	}

	public static String intToDWordString(int i) {
		return byteToHexString(intToDWord(i));
	}	
	
	public static byte[] longToDWord(long i) {
		byte[] result = new byte[4];
		result[0] = (byte) ((i >> 24) & 0xFF);
		result[1] = (byte) ((i >> 16) & 0xFF);
		result[2] = (byte) ((i >> 8) & 0xFF);
		result[3] = (byte) (i & 0xFF);
		return result;
	}

	public static byte[] longToWord(long i) {
		byte[] result = new byte[2];
		result[0] = (byte) ((i >> 8) & 0xFF);
		result[1] = (byte) (i & 0xFF);
		return result;
	}
	
	
    public static byte[] longTo8Bytes(long data)
    {
        byte[] bytes = new byte[8];
        bytes[7] = (byte) (data & 0xff);
        bytes[6] = (byte) ((data >> 8) & 0xff);
        bytes[5] = (byte) ((data >> 16) & 0xff);
        bytes[4] = (byte) ((data >> 24) & 0xff);
        bytes[3] = (byte) ((data >> 32) & 0xff);
        bytes[2] = (byte) ((data >> 40) & 0xff);
        bytes[1] = (byte) ((data >> 48) & 0xff);
        bytes[0] = (byte) ((data >> 56) & 0xff);
        return bytes;
    }	

	public static byte[] byteMerger(byte[] byte_1, byte[] byte_2) {
		if (byte_1 == null) {
			return null;
		}
		if (byte_2 == null) {
			return byte_1;
		}
		byte[] byte_3 = new byte[byte_1.length + byte_2.length];
		System.arraycopy(byte_1, 0, byte_3, 0, byte_1.length);
		System.arraycopy(byte_2, 0, byte_3, byte_1.length, byte_2.length);
		return byte_3;
	}
	
	public static String byteToHexString(byte data){
		String stmp = "";
		stmp = Integer.toHexString(data & 0xFF);
		stmp = (stmp.length() == 1) ? "0" + stmp : stmp;
		return stmp.toUpperCase().trim();
	}

	public static String byteToHexString(byte[] bytes) {

		if (bytes == null) {
			return null;
		}

		String stmp = "";
		StringBuilder sb = new StringBuilder("");
		for (int i = 0; i < bytes.length; i++) {

			stmp = Integer.toHexString(bytes[i] & 0xFF);
			sb.append((stmp.length() == 1) ? "0" + stmp : stmp);
		}
		stmp = sb.toString().toUpperCase().trim();
		return stmp;
	}



	public static byte[] hexStringToBytes(String hexString) {
		if (hexString == null || hexString.equals("")) {
			return null;
		}
		
		hexString = hexString.toUpperCase();
		if (hexString.startsWith("0X")){
			hexString = hexString.substring(2);
		}
		int length = hexString.length() / 2;
		char[] hexChars = hexString.toCharArray();
		byte[] d = new byte[length];
		for (int i = 0; i < length; i++) {
			int pos = i * 2;
			d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));

		}
		return d;
	}

	private static byte charToByte(char c) {
		return (byte) "0123456789ABCDEF".indexOf(c);
	}

	/**
	 * 生成校验码
	 * @param msg
	 * @return
	 */
	public static byte genCRC16(byte[] msg){
		byte CRC = msg[0];
        for (int i = 0; i < msg.length - 1;i++ )
        {
            CRC ^= msg[i + 1];
        }		
        return CRC;
	}

	public static String byte2ToBinString(byte[] b){
		return StringUtils.fillStr(Integer.toBinaryString(byte2ToInt(b)),"0",32,2);
	}
	
	public static String intToBinString(int i){
		return StringUtils.fillStr(Integer.toBinaryString(i),"0",32,2);
	}
	
	public static void main(String[] args) {
//		// byte[] bytes = new byte[2];
//		// bytes[0] = 0x00;
//		// bytes[1] = 0x0b;
//		// System.out.println(byte2ArrayToInt(bytes) & 1023);
//		System.out.println(ByteUtils.byteToHexString(ByteUtils.hexStringToBytes("0x8001")));
//		// 通过时间生成双字节的流水号
//		//System.out.println(wordToInt(longToWord(System.currentTimeMillis())));
//		
//		//测试转义
//		byte[] a = ByteUtils.hexStringToBytes("7e307e087d557e");
//		System.out.println(ByteUtils.byteToHexString(convert7E7D(a)));
//
//		//测试恢复转义
//		byte[] b = ByteUtils.hexStringToBytes("7E307D02087D01557E");
//		System.out.println(ByteUtils.byteToHexString(recover7E7D(b)));
//		
//		
//		System.out.println(ByteUtils.byteToHexString((byte)255));
//		
//		System.out.println(ByteUtils.byteToHexString(ByteUtils.genCRC16(ByteUtils.hexStringToBytes("0200002A9131971848730006000000050087B94301D16F7D068C237103220000001E15011922013701040001E848020200640302029E"))));
		
//		System.out.println(ByteUtils.byteToHexString("jxf".getBytes()));
//		System.out.println(intToBinString(0x00001003));  
//		System.out.println(ByteUtils.byte4ToInt(ByteUtils.hexStringToBytes("01CB998E")));
		byte[] b = ByteUtils.hexStringToBytes("464C432E00001500140085432F830000000000010202000100010001000000");
		byte crc = genCRC16(b);
		System.out.println(ByteUtils.byteToHexString(crc));

	}	
}
